import gradio as gr
import json
import os
import argparse
from datetime import datetime
from tools.opentargets import OpenTargetsManager, BioInfoError, OpenTargetsDataFormatter
from tools.pubmed import PubMedManager, PubMedDataFormatter
from tools.utils import ConfigManager as SharedConfigManager, DataFormatter

# 使用统一的配置管理器
OpenTargetsConfigManager = SharedConfigManager
PubMedConfigManager = SharedConfigManager

# 创建必要的目录
def create_directories():
    """创建结果保存目录"""
    os.makedirs(os.path.join('result', 'opentargets'), exist_ok=True)
    os.makedirs(os.path.join('result', 'pubmed'), exist_ok=True)

# 格式化结果为Gradio界面显示
def format_results_for_display(results, result_type):
    """格式化结果用于显示，返回Markdown格式字符串
    注意：此函数仅用于Gradio界面显示，而不是生成保存文件。
    生成保存文件统一使用DataFormatter.convert_to_markdown方法。"""
    if not results:
        return "未找到匹配结果"
    
    # 确保results是可切片的列表
    if isinstance(results, slice):
        # 如果传入的是slice对象，转换为空列表
        results = []
    elif not isinstance(results, list):
        # 尝试将非列表对象转换为列表
        try:
            results = list(results)
        except:
            # 如果转换失败，将其包装在列表中
            results = [results]
    
    try:
        # 根据不同结果类型格式化输出
        if result_type == "disease_drugs":
            output = []
            for item in results[:10]:  # 只显示前10个结果
                if not isinstance(item, dict):
                    continue
                drug = item.get('drug', {})
                if not isinstance(drug, dict):
                    drug = {}
                output.append(f"药物名称: {drug.get('name', 'N/A')}\n")
                output.append(f"  药物ID: {drug.get('id', 'N/A')}\n")
                output.append(f"  作用机制: {drug.get('mechanismOfAction', 'N/A')}\n")
                output.append(f"  治疗阶段: {drug.get('maximumPhaseForIndication', 'N/A')}\n")
                output.append("---\n")
            return ''.join(output)
        
        elif result_type == "target_associations":
            output = []
            for item in results[:10]:  # 只显示前10个结果
                if not isinstance(item, dict):
                    continue
                disease = item.get('disease', {})
                if not isinstance(disease, dict):
                    disease = {}
                output.append(f"疾病名称: {disease.get('name', 'N/A')}\n")
                output.append(f"  疾病ID: {disease.get('id', 'N/A')}\n")
                association_score = item.get('associationScore', {})
                if isinstance(association_score, dict):
                    output.append(f"  相关性分数: {association_score.get('overall', 'N/A')}\n")
                else:
                    output.append(f"  相关性分数: {association_score}\n")
                output.append("---\n")
            return ''.join(output)
        
        elif result_type == "disease_associations":
            output = []
            for item in results[:10]:  # 只显示前10个结果
                if not isinstance(item, dict):
                    continue
                target = item.get('target', {})
                if not isinstance(target, dict):
                    target = {}
                gene = target.get('gene', {})
                if not isinstance(gene, dict):
                    gene = {}
                output.append(f"靶点名称: {gene.get('symbol', 'N/A')}\n")
                output.append(f"  靶点ID: {target.get('id', 'N/A')}\n")
                association_score = item.get('associationScore', {})
                if isinstance(association_score, dict):
                    output.append(f"  相关性分数: {association_score.get('overall', 'N/A')}\n")
                else:
                    output.append(f"  相关性分数: {association_score}\n")
                output.append("---\n")
            return ''.join(output)
        
        elif result_type == "pubmed":
            output = []
            for item in results[:10]:  # 只显示前10个结果
                if not isinstance(item, dict):
                    continue
                output.append(f"**标题: {item.get('title', 'N/A')}**\n")
                authors = item.get('authors', [])
                if isinstance(authors, list):
                    output.append(f"  作者: {', '.join(authors)}\n")
                else:
                    output.append(f"  作者: {authors}\n")
                output.append(f"  期刊: {item.get('journal', 'N/A')}\n")
                output.append(f"  发表日期: {item.get('pub_date', 'N/A')}\n")
                output.append(f"  PMID: {item.get('pmid', 'N/A')}\n")
                output.append("---\n")
            return ''.join(output)
        
        else:
            # 通用JSON格式化
            if isinstance(results, list):
                return json.dumps(results[:5], indent=2, ensure_ascii=False)  # 限制显示前5个结果
            else:
                return json.dumps(results, indent=2, ensure_ascii=False)
    except Exception as e:
        print(f"格式化结果时出错: {str(e)}")
        return f"格式化结果时出错: {str(e)}"


# 存储全局状态
selected_disease = {}

# OpenTargets疾病药物查询功能
def query_disease_drugs(disease_name, disease_id, limit):
    """查询疾病相关药物"""
    try:
        create_directories()
        
        # 检查参数
        if not disease_name and not disease_id:
            return "请提供疾病名称或疾病ID", None, "", []
        
        # 使用绝对路径确保能找到配置文件
        config_path = os.path.join(os.path.dirname(__file__), "config.ini")
        config_manager = OpenTargetsConfigManager(config_path)
        ot_manager = OpenTargetsManager(config_manager)
        
        # 获取疾病ID
        if not disease_id:
            result = ot_manager.get_disease_efo_id(disease_name, interactive=False, for_gradio=True)
            
            # 检查是否有多个匹配结果
            if isinstance(result, tuple) and result[0] == "multiple_matches":
                # 存储匹配结果供后续使用
                selected_disease["hits"] = result[1]
                selected_disease["mode"] = "disease_drugs"
                selected_disease["limit"] = limit
                
                # 生成选择界面的HTML
                options = []
                disease_ids = []
                radio_options = []
                for i, hit in enumerate(result[1], 1):
                    # 尝试从不同字段获取疾病名称和ID
                    name = hit.get('name', hit.get('label', '未知名称'))
                    # 根据返回的数据结构获取ID
                    id_value = hit.get('id', '')
                    if not id_value and 'iri' in hit:
                        # 如果是OLS API返回的格式，从iri中提取ID
                        id_value = hit['iri'].split('/')[-1]
                    
                    options.append(f"{i}. {name} ({id_value})")
                    disease_ids.append(id_value)
                    radio_options.append(f"{name} (EFO ID: {id_value})")
                
                return f"# 找到多个匹配结果\n\n请从以下疾病中选择一个：\n\n" + "\n".join(options), None, "multiple_matches", radio_options
            else:
                disease_id = result
        
        # 查询疾病药物信息
        data = ot_manager.query_disease_drugs(disease_id, limit)
        
        # 保存结果
        result_dir = os.path.join('result', 'opentargets')
        current_date = datetime.now().strftime("%Y%m%d")
        filename = os.path.join(result_dir, f"{disease_id}_disease_drugs_size{limit}_{current_date}.json")
        DataFormatter.save_json(data, filename)
        
        # 转换为CSV格式
        OpenTargetsDataFormatter.convert_to_csv(data, filename, 'disease_drugs')
        
        # 创建ZIP归档
        zip_filename = DataFormatter.create_zip_archive(filename, include_csv=True, include_md=False)
        
        # 使用格式化函数显示结果
        display_result = format_results_for_display(data, 'disease_drugs')
        
        # 在Markdown内容前添加保存信息
        return f"# 疾病药物查询结果 - {disease_id}\n\n结果已保存到 {filename}\n\n{display_result}", zip_filename, "", None
    except BioInfoError as e:
        return f"错误: {str(e)}", None, "", None
    except Exception as e:
        return f"发生未预期错误: {str(e)}", None, "", None

# 处理疾病选择

def handle_disease_selection(selection_value):
    """处理疾病选择，支持单选按钮选择"""
    global selected_disease
    
    # 检查是否有匹配结果
    if "hits" not in selected_disease or not selected_disease["hits"]:
        return "错误：没有匹配的疾病结果", None
    
    # 检查选择值
    if not selection_value:
        return "错误：请选择一个疾病", None
    
    try:
        import re
        selected_hit = None
        
        # 尝试1: 通过单选按钮值中的ID提取
        # 支持多种格式的ID提取
        match = re.search(r'EFO ID: ([^\s)]+)', selection_value)
        if match:
            selected_efo_id = match.group(1)
            # 宽松匹配疾病ID
            for hit in selected_disease["hits"]:
                hit_id = hit.get('id', '')
                if not hit_id and 'iri' in hit:
                    hit_id = hit['iri'].split('/')[-1]
                
                # 尝试完整匹配或部分匹配
                if hit_id == selected_efo_id or hit_id.endswith('/' + selected_efo_id) or selected_efo_id.endswith('/' + hit_id):
                    selected_hit = hit
                    break
        
        # 尝试2: 如果还没找到，尝试从括号中提取任何ID格式
        if not selected_hit:
            match = re.search(r'\(([^)]+)\)', selection_value)
            if match:
                id_value = match.group(1)
                # 清理可能的前缀
                if 'EFO ID:' in id_value:
                    id_value = id_value.replace('EFO ID:', '').strip()
                
                # 用清理后的ID值查找
                for hit in selected_disease["hits"]:
                    hit_id = hit.get('id', '')
                    if not hit_id and 'iri' in hit:
                        hit_id = hit['iri'].split('/')[-1]
                    
                    if hit_id == id_value or id_value in hit_id or hit_id in id_value:
                        selected_hit = hit
                        break
        
        # 尝试3: 通过疾病名称匹配
        if not selected_hit:
            selection_text = selection_value.lower()
            for hit in selected_disease["hits"]:
                hit_name = hit.get('name', '').lower() or hit.get('label', '').lower()
                if hit_name in selection_text or selection_text in hit_name:
                    selected_hit = hit
                    break
        
        # 尝试4: 作为索引处理（兼容旧的数字输入方式）
        if not selected_hit:
            try:
                selection_index = int(selection_value)
                if 1 <= selection_index <= len(selected_disease["hits"]):
                    selected_hit = selected_disease["hits"][selection_index - 1]
            except ValueError:
                pass
        
        # 如果仍未找到匹配的疾病
        if not selected_hit:
            # 打印调试信息
            print(f"Debug - Selection value: {selection_value}")
            print(f"Debug - Available hits: {[hit.get('id', 'No ID') for hit in selected_disease['hits']]}")
            return "错误：未找到匹配的疾病", None
        
        # 获取疾病名称和ID
        disease_name = selected_hit.get('name', selected_hit.get('label', '未知名称'))
        disease_id = selected_hit.get('id', '')
        if not disease_id and 'iri' in selected_hit:
            # 如果是OLS API返回的格式，从iri中提取ID
            disease_id = selected_hit['iri'].split('/')[-1]
        
        # 根据不同的模式执行查询
        mode = selected_disease.get("mode", "disease_drugs")
        limit = selected_disease.get("limit", 100)
        
        # 初始化管理器
        config_path = os.path.join(os.path.dirname(__file__), "config.ini")
        config_manager = OpenTargetsConfigManager(config_path)
        ot_manager = OpenTargetsManager(config_manager)
        
        # 执行相应的查询
        if mode == "disease_drugs":
            data = ot_manager.query_disease_drugs(disease_id, limit)
        elif mode == "disease_associations":
            data = ot_manager.query_disease_associations(disease_id, limit)
        else:
            return "错误：未知的查询模式", None
        
        # 保存结果
        result_dir = os.path.join('result', 'opentargets')
        # 确保结果目录存在
        if not os.path.exists(result_dir):
            os.makedirs(result_dir, exist_ok=True)
            
        current_date = datetime.now().strftime("%Y%m%d")
        filename = os.path.join(result_dir, f"{disease_id}_{mode}_size{limit}_{current_date}.json")
        
        # 使用DataFormatter类处理文件保存和ZIP归档
        DataFormatter.save_json(data, filename)
        
        # 转换为CSV格式
        OpenTargetsDataFormatter.convert_to_csv(data, filename, mode)
        
        # 创建ZIP归档
        zip_filename = DataFormatter.create_zip_archive(filename, include_csv=True, include_md=False)
        
        # 使用格式化函数显示结果
        display_result = format_results_for_display(data, mode)
            
        # 在Markdown内容前添加疾病名称
        return f"# 查询结果 - {disease_name}\n\n{display_result}", zip_filename
    except BioInfoError as e:
        return f"错误: {str(e)}", None
    except Exception as e:
        print(f"Debug - Error: {str(e)}")
        return f"处理请求时发生错误: {str(e)}", None
        
        # 在Markdown内容前添加保存信息
        return f"# {disease_name} ({disease_id}) 查询结果\n\n结果已保存到 {filename}\n\n{display_result}", zip_filename
    except Exception as e:
        return f"错误：{str(e)}", None

# OpenTargets基因关联疾病查询功能
def query_target_associations(gene_name, limit):
    """查询基因关联疾病"""
    try:
        create_directories()
        
        if not gene_name:
            return "请提供基因名称", None
        
        # 使用绝对路径确保能找到配置文件
        config_path = os.path.join(os.path.dirname(__file__), "config.ini")
        config_manager = OpenTargetsConfigManager(config_path)
        ot_manager = OpenTargetsManager(config_manager)
        
        # 获取基因ID
        gene_id = ot_manager.get_ensembl_id(gene_name)
        
        # 查询基因关联疾病信息
        data = ot_manager.query_target_associations(gene_id, limit)
        
        # 保存结果
        result_dir = os.path.join('result', 'opentargets')
        current_date = datetime.now().strftime("%Y%m%d")
        filename = os.path.join(result_dir, f"{gene_id}_target_associations_size{limit}_{current_date}.json")
        DataFormatter.save_json(data, filename)
        
        # 转换为CSV格式
        OpenTargetsDataFormatter.convert_to_csv(data, filename, 'target_associations')
        
        # 创建ZIP归档
        zip_filename = DataFormatter.create_zip_archive(filename, include_csv=True, include_md=False)
        
        # 使用格式化函数显示结果
        display_result = format_results_for_display(data, 'target_associations')
        
        # 在Markdown内容前添加保存信息
        return f"# 基因关联疾病查询结果 - {gene_name}\n\n结果已保存到 {filename}\n\n{display_result}", zip_filename
    except BioInfoError as e:
        return f"错误: {str(e)}", None
    except Exception as e:
        return f"发生未预期错误: {str(e)}", None

# OpenTargets疾病关联靶点查询功能
def query_disease_associations(disease_name, disease_id, limit):
    """查询疾病关联靶点"""
    try:
        create_directories()
        
        # 检查参数
        if not disease_name and not disease_id:
            return "请提供疾病名称或疾病ID", None, "", []
        
        # 使用绝对路径确保能找到配置文件
        config_path = os.path.join(os.path.dirname(__file__), "config.ini")
        config_manager = OpenTargetsConfigManager(config_path)
        ot_manager = OpenTargetsManager(config_manager)
        
        # 获取疾病ID
        if not disease_id:
            result = ot_manager.get_disease_efo_id(disease_name, interactive=False, for_gradio=True)
            
            # 检查是否有多个匹配结果
            if isinstance(result, tuple) and result[0] == "multiple_matches":
                # 存储匹配结果供后续使用
                selected_disease["hits"] = result[1]
                selected_disease["mode"] = "disease_associations"
                selected_disease["limit"] = limit
                
                # 生成选择界面的HTML
                options = []
                disease_ids = []
                radio_options = []
                for i, hit in enumerate(result[1], 1):
                    # 尝试从不同字段获取疾病名称和ID
                    name = hit.get('name', hit.get('label', '未知名称'))
                    # 根据返回的数据结构获取ID
                    id_value = hit.get('id', '')
                    if not id_value and 'iri' in hit:
                        # 如果是OLS API返回的格式，从iri中提取ID
                        id_value = hit['iri'].split('/')[-1]
                    
                    options.append(f"{i}. {name} ({id_value})")
                    disease_ids.append(id_value)
                    radio_options.append(f"{name} (EFO ID: {id_value})")
                
                return f"# 找到多个匹配结果\n\n请从以下疾病中选择一个：\n\n" + "\n".join(options), None, "multiple_matches", radio_options
            else:
                disease_id = result
        
        # 查询疾病关联靶点信息
        data = ot_manager.query_disease_associations(disease_id, limit)
        
        # 保存结果
        result_dir = os.path.join('result', 'opentargets')
        current_date = datetime.now().strftime("%Y%m%d")
        filename = os.path.join(result_dir, f"{disease_id}_disease_associations_size{limit}_{current_date}.json")
        DataFormatter.save_json(data, filename)
        
        # 转换为CSV格式
        OpenTargetsDataFormatter.convert_to_csv(data, filename, 'disease_associations')
        
        # 创建ZIP归档
        zip_filename = DataFormatter.create_zip_archive(filename, include_csv=True, include_md=False)
        
        # 使用格式化函数显示结果
        display_result = format_results_for_display(data, 'disease_associations')
        
        # 在Markdown内容前添加保存信息
        return f"# 疾病关联靶点查询结果 - {disease_id}\n\n结果已保存到 {filename}\n\n{display_result}", zip_filename, "", None
    except BioInfoError as e:
        return f"错误: {str(e)}", None, "", None
    except Exception as e:
        return f"发生未预期错误: {str(e)}", None, "", None

# PubMed搜索功能
def search_pubmed(query, limit=100):
    """PubMed搜索"""
    try:
        create_directories()
        
        if not query:
            return "请提供搜索关键词", None
        
        # 使用绝对路径确保能找到配置文件
        config_path = os.path.join(os.path.dirname(__file__), "config.ini")
        config_manager = PubMedConfigManager(config_path)
        pubmed_manager = PubMedManager(config_manager)
        
        # 搜索文章
        id_list = pubmed_manager.search_pubmed(query, limit=limit)
        
        if not id_list:
            return "未找到与查询关键词匹配的文章，请尝试其他关键词。", None
        
        # 获取文章记录并提取信息
        records = pubmed_manager.fetch_pubmed_records(id_list)
        results = pubmed_manager.extract_info(records)
        
        # 保存结果
        result_dir = os.path.join('result', 'pubmed')
        current_date = datetime.now().strftime("%Y%m%d_%H%M%S")
        safe_query = query.replace('/', '_').replace('\\', '_').replace(':', '_')
        filename = os.path.join(result_dir, f"{safe_query}_size{limit}_{current_date}.json")
        DataFormatter.save_json(results, filename)
        
        # 转换为Markdown格式并保存
        PubMedDataFormatter.convert_to_markdown(results, filename)
        
        # 创建ZIP归档（包含JSON和Markdown文件）
        zip_filename = DataFormatter.create_zip_archive(filename, include_csv=False, include_md=True)
        
        # 直接生成带换行格式的Markdown内容
        display_result = []
        for i, result in enumerate(results, 1):
            display_result.append(f"### 结果 {i}")
            display_result.append("**标题:**")
            display_result.append(f"**{result['title']}**")
            display_result.append("**摘要:**")
            display_result.append(result['abstract'])
            display_result.append("**出处:**")
            display_result.append(result['citation'])
            display_result.append("")  # 空行分隔
        
        # 合并结果
        display_result_text = '\n'.join(display_result)
        
        # 在Markdown内容前添加保存信息
        return f"# PubMed搜索结果 - {query}\n\n结果已保存到 {filename}\n\n{display_result_text}", zip_filename
    except BioInfoError as e:
        return f"错误: {str(e)}", None
    except Exception as e:
        return f"发生未预期错误: {str(e)}", None

# 创建Gradio界面
def create_interface():
    """创建Gradio Web界面"""
    with gr.Blocks(title="VeritasGene - 生物信息学工具集") as interface:
        gr.Markdown("""# VeritasGene
        
        集成OpenTargets和PubMed查询功能的检索工具
        """)
        
        # 选项卡式界面
        with gr.Tabs():
            # OpenTargets疾病药物查询选项卡
            with gr.TabItem("OpenTargets疾病药物查询"):
                with gr.Row():
                    with gr.Column(scale=1):
                        disease_drugs_disease_name = gr.Textbox(label="疾病名称（可选）")
                        disease_drugs_disease_id = gr.Textbox(label="疾病ID（EFO ID，可选）")
                        disease_drugs_limit = gr.Slider(minimum=1, maximum=500, value=100, step=1, label="结果数量限制")
                        disease_drugs_button = gr.Button("查询", variant="primary")
                        # 添加疾病选择组件
                        disease_drugs_selection_mode = gr.State("single")
                        disease_drugs_selection_state = gr.State([])
                        disease_drugs_selection_group = gr.Group(visible=False)
                        with disease_drugs_selection_group:
                            gr.Markdown("请选择以下匹配的疾病之一：")
                            disease_drugs_selection_radio = gr.Radio([], label="选择疾病", interactive=True)
                    with gr.Column(scale=2):
                        disease_drugs_zip = gr.File(label="下载结果(ZIP)")
                        disease_drugs_output = gr.Markdown(label="查询结果", value="点击查询按钮开始查询")
                
                # 查询按钮点击事件
                disease_drugs_button.click(
                    fn=query_disease_drugs,
                    inputs=[disease_drugs_disease_name, disease_drugs_disease_id, disease_drugs_limit],
                    outputs=[disease_drugs_output, disease_drugs_zip, disease_drugs_selection_mode, disease_drugs_selection_state]
                )
                
                # 监听选择模式和状态变化，显示或隐藏选择组件
                def toggle_selection_radio(mode, selection_state):
                    if mode == "multiple_matches" and selection_state:
                        return gr.update(visible=True), gr.update(choices=selection_state, interactive=True)
                    return gr.update(visible=False), gr.update(choices=[], interactive=False)
                
                # 当检测到多个匹配时显示选择组件
                disease_drugs_selection_mode.change(
                    fn=toggle_selection_radio,
                    inputs=[disease_drugs_selection_mode, disease_drugs_selection_state],
                    outputs=[disease_drugs_selection_group, disease_drugs_selection_radio]
                )
                
                # 单选按钮值变化时自动处理选择
                disease_drugs_selection_radio.change(
                    fn=handle_disease_selection,
                    inputs=[disease_drugs_selection_radio],
                    outputs=[disease_drugs_output, disease_drugs_zip]
                )
            
            # OpenTargets基因关联疾病查询选项卡
            with gr.TabItem("OpenTargets基因关联疾病查询"):
                with gr.Row():
                    with gr.Column(scale=1):
                        target_associations_gene_name = gr.Textbox(label="基因名称")
                        target_associations_limit = gr.Slider(minimum=1, maximum=500, value=100, step=1, label="结果数量限制")
                        target_associations_button = gr.Button("查询", variant="primary")
                    with gr.Column(scale=2):
                        target_associations_zip = gr.File(label="下载结果(ZIP)")
                        target_associations_output = gr.Markdown(label="查询结果", value="点击查询按钮开始查询")
                
                target_associations_button.click(
                    fn=query_target_associations,
                    inputs=[target_associations_gene_name, target_associations_limit],
                    outputs=[target_associations_output, target_associations_zip]
                )
            
            # OpenTargets疾病关联靶点查询选项卡
            with gr.TabItem("OpenTargets疾病关联靶点查询"):
                with gr.Row():
                    with gr.Column(scale=1):
                        disease_associations_disease_name = gr.Textbox(label="疾病名称（可选）")
                        disease_associations_disease_id = gr.Textbox(label="疾病ID（EFO ID，可选）")
                        disease_associations_limit = gr.Slider(minimum=1, maximum=500, value=100, step=1, label="结果数量限制")
                        disease_associations_button = gr.Button("查询", variant="primary")
                        # 添加疾病选择组件
                        disease_associations_selection_mode = gr.State("single")
                        disease_associations_selection_state = gr.State([])
                        disease_associations_selection_group = gr.Group(visible=False)
                        with disease_associations_selection_group:
                            gr.Markdown("请选择以下匹配的疾病之一：")
                            disease_associations_selection_radio = gr.Radio([], label="选择疾病", interactive=True)
                    with gr.Column(scale=2):
                        disease_associations_zip = gr.File(label="下载结果(ZIP)")
                        disease_associations_output = gr.Markdown(label="查询结果", value="点击查询按钮开始查询")
                
                # 查询按钮点击事件
                disease_associations_button.click(
                    fn=query_disease_associations,
                    inputs=[disease_associations_disease_name, disease_associations_disease_id, disease_associations_limit],
                    outputs=[disease_associations_output, disease_associations_zip, disease_associations_selection_mode, disease_associations_selection_state]
                )
                
                # 监听选择模式和状态变化，显示或隐藏选择组件
                def toggle_selection_radio(mode, selection_state):
                    if mode == "multiple_matches" and selection_state:
                        return gr.update(visible=True), gr.update(choices=selection_state, interactive=True)
                    return gr.update(visible=False), gr.update(choices=[], interactive=False)
                
                # 当检测到多个匹配时显示选择组件
                disease_associations_selection_mode.change(
                    fn=toggle_selection_radio,
                    inputs=[disease_associations_selection_mode, disease_associations_selection_state],
                    outputs=[disease_associations_selection_group, disease_associations_selection_radio]
                )
                
                # 单选按钮值变化时自动处理选择
                disease_associations_selection_radio.change(
                    fn=handle_disease_selection,
                    inputs=[disease_associations_selection_radio],
                    outputs=[disease_associations_output, disease_associations_zip]
                )
            
            # PubMed搜索选项卡
            with gr.TabItem("PubMed搜索"):
                with gr.Row():
                    with gr.Column(scale=1):
                        pubmed_query = gr.Textbox(label="搜索关键词")
                        pubmed_limit = gr.Slider(minimum=1, maximum=500, value=100, step=1, label="结果数量限制")
                        pubmed_button = gr.Button("搜索", variant="primary")
                    with gr.Column(scale=2):
                        pubmed_zip = gr.File(label="下载结果(ZIP)")
                        pubmed_output = gr.Markdown(label="搜索结果", value="点击搜索按钮开始查询")
                
                pubmed_button.click(
                    fn=search_pubmed,
                    inputs=[pubmed_query, pubmed_limit],
                    outputs=[pubmed_output, pubmed_zip]
                )
    
    return interface

# 启动应用
if __name__ == "__main__":
    # 创建参数解析器
    parser = argparse.ArgumentParser(description="VeritasGene Web界面")
    parser.add_argument("--port", type=int, default=7860, help="指定服务器端口号（默认：7860）")
    
    # 解析命令行参数
    args = parser.parse_args()
    
    # 创建并启动界面
    interface = create_interface()
    # 启动Gradio服务器，使用指定的端口
    interface.launch(server_name="0.0.0.0", server_port=args.port)